package com.yuantu.judiciary.serviceimpl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.alibaba.excel.EasyExcel;
import com.yuantu.judiciary.common.SysOnOffState;
import com.yuantu.judiciary.dao.*;
import com.yuantu.judiciary.exception.enums.*;
import com.yuantu.judiciary.model.domain.*;
import com.yuantu.judiciary.model.enums.*;
import com.yuantu.judiciary.model.form.AddUserForm;
import com.yuantu.judiciary.model.form.ModifyUserForm;
import com.yuantu.judiciary.model.form.SearchEnterFrom;
import com.yuantu.judiciary.model.form.SearchEnterUserFrom;
import com.yuantu.judiciary.model.vo.*;
import com.yuantu.judiciary.security.handler.OrganizationInfoListener;
import com.yuantu.judiciary.service.ICheckEnterpriseService;
import com.yuantu.judiciary.service.IOrganizationService;
import com.yuantu.judiciary.utils.AssertUtil;
import com.yuantu.judiciary.utils.ExcelUtil;
import com.yuantu.judiciary.utils.StringUtil;
import com.yuantu.judiciary.utils.TimeUtil;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 组织管理模块
 *
 * @author syw
 * @since 2023-08-12
 **/
@Service
@RequiredArgsConstructor
public class OrganizationServiceImpl implements IOrganizationService {

    private final IOrganizationDao organizationDao;
    private final IAccountDao accountDao;
    private final IUserInfoDao userInfoDao;
    private final IOrgVipRecordDao orgVipRecordDao;
    private final IOrganizationSourceDao organizationSourceDao;
    private final ICheckEnterpriseService enterpriseService;
    private final IInviteCodeDao inviteCodeDao;
    private final IInviteRecordDao inviteRecordDao;

    @Override
    public PageVO<QueryEnterVO> searchEnterPage(SearchEnterFrom form, Pageable pageable) {
        Timestamp startTime = ObjectUtils.isEmpty(form.getStartTime()) ? null : TimeUtil.getDayBeginTime(form.getStartTime());
        Timestamp endTime = ObjectUtils.isEmpty(form.getEndTime()) ? null : TimeUtil.getDayEndTime(form.getEndTime());
        Page<OrganizationDO> page = organizationDao.findOrgByEnterNameLikeAndAuthStateAndCreateTime(
                form.getName(), form.getState(), startTime, endTime, OrganizationType.ENTER, form.getIsSource(), pageable
        );

        Map<Long, OrganizationSourceDO> orgSourceMap = organizationSourceDao.findAllInfos().stream().
                collect(Collectors.toMap(OrganizationSourceDO::getId, Function.identity()));

        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            QueryEnterVO queryEnterVO = new QueryEnterVO();
            Long organizationSourceId = data.getOrganizationSourceId();
            BeanUtils.copyProperties(data, queryEnterVO);
            OrganizationSourceDO orgSource = orgSourceMap.getOrDefault(organizationSourceId, new OrganizationSourceDO());
            queryEnterVO.setOrgSource(orgSource.getOrgSource());
            queryEnterVO.setOrgSourceId(organizationSourceId);
            queryEnterVO.setNeedEntAuthFile(orgSource.getEntAuth());
            queryEnterVO.setNeedPerAuthFile(orgSource.getPerAuth());
            queryEnterVO.setState(data.getAuthState());
            return queryEnterVO;
        }).collect(Collectors.toList()));
    }

    @Override
    public PageVO<QueryEnterUserVO> searchEnterUserPage(SearchEnterUserFrom form, Pageable pageable) {
        Page<IAccountDao.SimpleAccountInfo> simpleAccountInfo = accountDao.getSimpleAccountInfoByUsernameAndPhone(form.getId(), form.getUsername(), form.getPhone(), pageable);

        return new PageVO<>(simpleAccountInfo.getTotalElements(), simpleAccountInfo.getContent().stream()
                .map(data -> {
                    QueryEnterUserVO res = new QueryEnterUserVO();
                    res.setUsername(data.getUsername());
                    res.setPhone(data.getPhone());
                    res.setType(data.getType());
                    return res;
                }).collect(Collectors.toList()));
    }

    @Override
    public PageVO<QuerySingleVO> searchSinglePage(SearchEnterFrom form, Pageable pageable) {
        Timestamp startTime = ObjectUtils.isEmpty(form.getStartTime()) ? null : TimeUtil.getDayBeginTime(form.getStartTime());
        Timestamp endTime = ObjectUtils.isEmpty(form.getEndTime()) ? null : TimeUtil.getDayEndTime(form.getEndTime());
        Page<OrganizationDO> page = organizationDao.findOrgByUsernameLikeAndAuthStateAndCreateTime(
                form.getName(), form.getState(), startTime, endTime, OrganizationType.SINGLE, pageable
        );

        return new PageVO<>(page.getTotalElements(), page.getContent().stream().map(data -> {
            QuerySingleVO queryEnterVO = new QuerySingleVO();
            BeanUtils.copyProperties(data, queryEnterVO);
            queryEnterVO.setState(data.getAuthState());
            return queryEnterVO;
        }).collect(Collectors.toList()));
    }

    @Override
    public List<AccountListVO> getUserList(Long accountId) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);

        List<AccountDO> accountList = accountDao.findAccountByOrganizationIdAndDeletedFalse(account.getOrganizationId());
        if (CollectionUtils.isEmpty(accountList)) {
            return Collections.emptyList();
        }
        List<Long> userIds = accountList.stream().map(AccountDO::getUserId).collect(Collectors.toList());
        Map<Long, String> userMap = userInfoDao.findUserByIdInAndDeletedFalse(userIds).stream().collect(
                Collectors.toMap(UserInfoDO::getId, UserInfoDO::getPhone)
        );

        return accountList.stream().sorted(
                Comparator.comparing(AccountDO::getType).thenComparing(Comparator.comparing(AccountDO::getId).reversed())
        ).map(data ->
                new AccountListVO(data.getId(), data.getUsername(), userMap.getOrDefault(data.getUserId(), ""),
                        data.getType())
        ).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUser(Long accountId, AddUserForm form) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        AssertUtil.assertTrue(UserType.PRIMARY.equals(account.getType()), AccountExceptionEnum.ACCOUNT_NOT_PRIMARY);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
        List<AccountDO> accountList = accountDao.findAccountByOrganizationIdAndDeletedFalse(account.getOrganizationId());
        OrgVipRecordDO vipRecord = orgVipRecordDao.findRecordByOrganizationIdAndDeletedFalse(organization.getId());
        boolean verify = !ObjectUtils.isEmpty(vipRecord) && !ObjectUtils.isEmpty(vipRecord.getAccountNum()) && vipRecord.getAccountNum() > accountList.size();
        AssertUtil.assertTrue(verify, VipExceptionEnum.VIP_ACCOUNT_NUM_EXCEED);

        UserInfoDO userInfo = userInfoDao.findByPhoneAndDeletedFalse(form.getPhone());
        //AssertUtil.assertTrue(!ObjectUtils.isEmpty(userInfo), UserExceptionEnum.USER_NOT_EXIST);
        if(userInfo == null){
            userInfo = new UserInfoDO();
            userInfo.setPhone(form.getPhone());
            userInfo.setUserName(form.getName());
            userInfoDao.save(userInfo);
        }
        List<AccountDO> accounts = accountDao.findByUserIdAndTypeInAndDeletedFalse(userInfo.getId(), Arrays.asList(UserType.PRIMARY, UserType.SUB, UserType.NONE));
        AccountDO addAccount;
        if (CollectionUtils.isEmpty(accounts)) {
            addAccount = new AccountDO();
            addAccount.setUsername(form.getName());
            addAccount.setUserId(userInfo.getId());
            addAccount.setState(SysOnOffState.ON);
            addAccount.setType(form.getType());
            addAccount.setOrganizationId(organization.getId());
        } else {
            boolean isExist = accounts.stream().anyMatch(data -> organization.getId().equals(data.getOrganizationId()));
            AssertUtil.assertTrue(!isExist, UserExceptionEnum.USER_EXIST);

            List<AccountDO> validAccount = accounts.stream()
                    .filter(data -> ObjectUtils.isEmpty(data.getOrganizationId()) && UserType.NONE.equals(data.getType()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(validAccount)) {
                addAccount = new AccountDO();
                addAccount.setUsername(form.getName());
                addAccount.setUserId(userInfo.getId());
                addAccount.setState(SysOnOffState.ON);
                addAccount.setType(form.getType());
                addAccount.setOrganizationId(organization.getId());
            } else {
                addAccount = validAccount.get(0);
                addAccount.setOrganizationId(organization.getId());
                addAccount.setType(form.getType());
            }
        }
        accountDao.save(addAccount);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyUser(Long accountId, ModifyUserForm form) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        AssertUtil.assertTrue(UserType.PRIMARY.equals(account.getType()), AccountExceptionEnum.ACCOUNT_NOT_PRIMARY);
        AccountDO modifyAccount = accountDao.findByIdAndDeletedFalse(form.getId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(modifyAccount), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(modifyAccount.getOrganizationId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);

        List<AccountDO> accountList = accountDao.findAccountByOrganizationIdAndDeletedFalse(modifyAccount.getOrganizationId());
        List<AccountDO> primaryAccount = accountList.stream().filter(data -> UserType.PRIMARY.equals(data.getType())).collect(Collectors.toList());
        boolean verify = primaryAccount.size() == 1 && primaryAccount.get(0).getId().equals(form.getId()) && UserType.SUB.equals(form.getType());
        AssertUtil.assertTrue(!verify, AccountExceptionEnum.ACCOUNT_AT_LEAST_ONE);
        modifyAccount.setType(form.getType());
        accountDao.save(modifyAccount);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long accountId, List<Long> id) {
        AccountDO account = accountDao.findByIdAndDeletedFalse(accountId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(account), AccountExceptionEnum.ACCOUNT_NOT_EXIST);
        AssertUtil.assertTrue(UserType.PRIMARY.equals(account.getType()), AccountExceptionEnum.ACCOUNT_NOT_PRIMARY);
        OrganizationDO organization = organizationDao.findByIdAndDeletedFalse(account.getOrganizationId());
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organization), OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);

        List<AccountDO> accountList = accountDao.findAccountByOrganizationIdAndDeletedFalse(account.getOrganizationId());
        List<AccountDO> primaryAccount = accountList.stream().filter(data -> UserType.PRIMARY.equals(data.getType())).collect(Collectors.toList());
        boolean verify = primaryAccount.size() == 1 && primaryAccount.get(0).getId().equals(accountId) && id.contains(accountId);
        AssertUtil.assertTrue(!verify, AccountExceptionEnum.ACCOUNT_AT_LEAST_ONE);

        accountDao.deleteByIdIn(id, accountId, new Timestamp(System.currentTimeMillis()));
        return true;
    }

    @Override
    public Boolean uploadSourceEnterInfos(MultipartFile file, Long organizationSourceId) {

        OrganizationSourceDO organizationSource = organizationSourceDao.findInfoByIdAndDeletedFalse(organizationSourceId);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(organizationSource), OrganizationExceptionEnum.ORGANIZATION_SOURCE_NOT_EXIST);
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(0);
        params.setNeedVerify(false);
        List<OrganizationNameVO> organizationNameInfos;
        try {
            ExcelImportResult<OrganizationNameVO> excelImportResult = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    OrganizationNameVO.class, params);
            organizationNameInfos = excelImportResult.getList();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Pageable pageable = PageRequest.of(0, 10);
        if (!CollectionUtils.isEmpty(organizationNameInfos)) {
            for (OrganizationNameVO organizationNameInfo : organizationNameInfos) {
                String name = organizationNameInfo.getName();
                PageVO<EntListVO> enterprisePageInfo = enterpriseService.getEnterpriseList(name, pageable);
                List<EntListVO> enterInfos = enterprisePageInfo.getData();
                Optional<EntListVO> first = Optional.ofNullable(enterInfos)
                        .map(Collection::stream)
                        .orElseGet(Stream::empty)
                        .filter(s -> name != null && name.equals(s.getEnterpriseName()))
                        .findFirst();
                if (first.isPresent()) {
                    EntListVO entList = first.get();
                    if (!StringUtil.isEmpty(entList.getCreditCode())) {
                        OrganizationDO organization = organizationDao.findInfoByCreditCodeAndDeletedFalse(entList.getCreditCode());
                        if (organization == null) {
                            organization = new OrganizationDO();
                            organization.setEnterName(name);
                            organization.setType(OrganizationType.ENTER);
                            organization.setAuthState(AuthState.PASS);
                            organization.setState(SysOnOffState.ON);
                            organization.setCreditCode(entList.getCreditCode());
                            organization.setOrganizationSourceId(organizationSourceId);
                        } else {
                            Long existOrganizationSourceId = organization.getOrganizationSourceId();
                            if (existOrganizationSourceId == null) {
                                organization.setOrganizationSourceId(organizationSourceId);
                            }
                        }
                        organizationDao.save(organization);
                    }
                }
            }
        }
        // todo 创建用户绑定企业关系

        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean uploadEnterUseTimes(MultipartFile file, String codeInfo) {

        InviteCodeDO inviteCode = inviteCodeDao.findCodeByInviteCodeAndDeletedFalse(codeInfo);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(inviteCode), InviteCodeExceptionEnum.INVITE_CODE_NOT_EXIST);
        AssertUtil.assertTrue(InviteCodeType.DIVIDE_USE.equals(inviteCode.getType()), InviteCodeExceptionEnum.INVITE_CODE_TYPE_ERROR);
        Date now = new Date();
        AssertUtil.assertTrue(now.before(inviteCode.getExpiresTime()), InviteCodeExceptionEnum.INVITE_CODE_EXPIRED);
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(inviteCode.getUseTimes()), InviteCodeExceptionEnum.USE_TIMES_NOT_EXIST);
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(0);
        params.setNeedVerify(false);
        List<OrganizationDivideUseVO> organizationDivideUseInfos;
        try {
            ExcelImportResult<OrganizationDivideUseVO> excelImportResult = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    OrganizationDivideUseVO.class, params);
            organizationDivideUseInfos = excelImportResult.getList();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        AssertUtil.assertTrue(!CollectionUtils.isEmpty(organizationDivideUseInfos), OrganizationExceptionEnum.ORGANIZATION_DIVIDE_USE_INFO_EMPTY);
        List<InviteRecordDO> inviteRecords = inviteRecordDao.findRecordByInviteCodeAndTypeAndDeletedFalse(codeInfo, InviteCodeType.DIVIDE_USE);
        Integer dividedUseTimes = inviteRecords.stream().mapToInt(InviteRecordDO::getUseTimes).sum();
        int divideUseTimes = inviteCode.getUseTimes() - dividedUseTimes;
        int wantDivideUseTimes = organizationDivideUseInfos.stream().mapToInt(OrganizationDivideUseVO::getDivideTimes).sum();
        if (wantDivideUseTimes > divideUseTimes) {
            throw new RuntimeException("分配使用次数超出剩余次数,剩余次数为" + divideUseTimes);
        }
        for (OrganizationDivideUseVO organizationDivideUseInfo : organizationDivideUseInfos) {
            String phone = organizationDivideUseInfo.getPhone();
            UserInfoDO userInfo = userInfoDao.findByPhoneAndDeletedFalse(phone);
            if (userInfo == null) {
                userInfo = new UserInfoDO();
                userInfo.setUserName(organizationDivideUseInfo.getUserName());
                userInfo.setPhone(phone);
            }else {
                userInfo.setUserName(organizationDivideUseInfo.getUserName());
            }
            userInfoDao.save(userInfo);
            List<AccountDO> accountInfos = accountDao.findByUserIdAndTypeInAndDeletedFalse(userInfo.getId(), Collections.singletonList(UserType.PRIMARY));
            List<Long> existOrganizationIds = accountInfos.stream().map(AccountDO::getOrganizationId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(existOrganizationIds)) {
                existOrganizationIds = organizationDao.findByIdInAndDeletedFalse(existOrganizationIds).stream().
                        filter(s -> !OrganizationType.ALIPAY.equals(s.getType())).map(OrganizationDO::getId).collect(Collectors.toList());
                List<Long> finalExistOrganizationIds = existOrganizationIds;
                accountInfos = accountInfos.stream().filter(f -> finalExistOrganizationIds.contains(f.getOrganizationId())).collect(Collectors.toList());
            }
            AccountDO account;
            OrganizationDO organization;
            if (CollectionUtils.isEmpty(accountInfos)) {
                account = new AccountDO();
                organization = new OrganizationDO();
                organization.setUsername(organizationDivideUseInfo.getUserName());
                organization.setPhone(phone);
                organization.setType(OrganizationType.ENTER);
                organization.setEnterName(organizationDivideUseInfo.getEnterName());
                organization.setAuthState(AuthState.PASS);
                organization.setState(SysOnOffState.ON);
                organization.setOrganizationSourceId(1L);
                organizationDao.save(organization);
                account.setUsername(organizationDivideUseInfo.getUserName());
                account.setType(UserType.PRIMARY);
                account.setUserId(userInfo.getId());
                account.setOrganizationId(organization.getId());
                account.setState(SysOnOffState.ON);
                account.setEnterName(organizationDivideUseInfo.getEnterName());
                account.setOrigin(EndpointType.APPLET);
                account.setPointScale(1);
                account.setHistoryScore(0.0);
                account.setMembershipRankId(1L);
                accountDao.save(account);
            } else {
                List<Long> organizationIds = accountInfos.stream().map(AccountDO::getOrganizationId).distinct().collect(Collectors.toList());
                List<OrganizationDO> existOrgInfos = organizationDao.findByIdInAndDeletedFalse(organizationIds);
                Optional<OrganizationDO> first = existOrgInfos.stream().filter(s -> organizationDivideUseInfo.getEnterName().equals(s.getEnterName())).findFirst();
                if (first.isPresent()) {
                    organization = first.get();
                    Long organizationId = organization.getId();
                    Map<Long, AccountDO> accountMap = accountInfos.stream().collect(Collectors.toMap(AccountDO::getOrganizationId,
                            Function.identity(), (s1, s2) -> s2));
                    account = accountMap.get(organizationId);
                    account.setUsername(organizationDivideUseInfo.getUserName());
                    accountDao.save(account);
                } else {
                    account = new AccountDO();
                    organization = new OrganizationDO();
                    organization.setUsername(organizationDivideUseInfo.getUserName());
                    organization.setPhone(phone);
                    organization.setType(OrganizationType.ENTER);
                    organization.setEnterName(organizationDivideUseInfo.getEnterName());
                    organization.setAuthState(AuthState.PASS);
                    organization.setState(SysOnOffState.ON);
                    organization.setOrganizationSourceId(1L);
                    organizationDao.save(organization);
                    account.setUsername(organizationDivideUseInfo.getUserName());
                    account.setType(UserType.PRIMARY);
                    account.setUserId(userInfo.getId());
                    account.setOrganizationId(organization.getId());
                    account.setState(SysOnOffState.ON);
                    account.setEnterName(organizationDivideUseInfo.getEnterName());
                    account.setOrigin(EndpointType.APPLET);
                    account.setPointScale(1);
                    account.setHistoryScore(0.0);
                    account.setMembershipRankId(1L);
                    accountDao.save(account);
                }
            }
            InviteRecordDO inviteRecord = new InviteRecordDO();
            inviteRecord.setType(inviteCode.getType());
            inviteRecord.setInviteCode(inviteCode.getInviteCode());
            inviteRecord.setOrganizationId(organization.getId());
            inviteRecord.setInviteTime(inviteCode.getExpiresTime());
            inviteRecord.setUseTimes(organizationDivideUseInfo.getDivideTimes());
            inviteRecord.setCreatorId(account.getId());
            inviteRecordDao.save(inviteRecord);
        }
        return true;
    }


    @Override
    public void downloadSourceEnterInfos(Long organizationSourceId, MultipartFile file, HttpServletResponse response) {
        List<OrganizationDO> organizationInfos = organizationDao.findInfosByOrganizationSourceIdAndDeletedFalse(organizationSourceId);
        List<OrganizationNameVO> organizationNameInfos = new ArrayList<>();
        for (OrganizationDO organizationInfo : organizationInfos) {
            OrganizationNameVO organizationName = new OrganizationNameVO();
            organizationName.setName(organizationInfo.getEnterName());
            organizationNameInfos.add(organizationName);
        }
        List<String> orgNames = organizationInfos.stream().map(OrganizationDO::getEnterName).collect(Collectors.toList());
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setTitleRows(0);
        params.setNeedVerify(false);
        List<OrganizationNameVO> existOrganizationNameInfos;
        try {
            ExcelImportResult<OrganizationNameVO> excelImportResult = ExcelImportUtil.importExcelMore(file.getInputStream(),
                    OrganizationNameVO.class, params);
            existOrganizationNameInfos = excelImportResult.getList();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        existOrganizationNameInfos = existOrganizationNameInfos.stream().filter(s -> !orgNames.contains(s.getName())).collect(Collectors.toList());
        try {
            ExcelUtil.exportExcel("企业信息", "企业信息", OrganizationNameVO.class, existOrganizationNameInfos,
                    "企业信息", response);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public PageVO<OrgSourceOrganizationVO> querySourceEnterInfos(OrgSourceOrganizationQueryVO query, Pageable pageable) {

        Page<OrganizationDO> organizationPageInfo = organizationDao.findOrgSourceInfos(query, pageable);
        List<OrganizationDO> content = organizationPageInfo.getContent();
        if (CollectionUtils.isEmpty(content)) {
            return new PageVO<>(organizationPageInfo.getTotalElements(), Collections.emptyList());
        }
        Map<Long, OrganizationSourceDO> orgSourceMap = organizationSourceDao.findAllInfos().stream().
                collect(Collectors.toMap(OrganizationSourceDO::getId, Function.identity()));
        List<OrgSourceOrganizationVO> result = new ArrayList<>();
        for (OrganizationDO organization : content) {
            OrgSourceOrganizationVO orgSourceOrganization = new OrgSourceOrganizationVO();
            orgSourceOrganization.setOrganizationId(organization.getId());
            orgSourceOrganization.setEnterName(organization.getEnterName());
            orgSourceOrganization.setEnterAddr(organization.getEnterAddr());
            orgSourceOrganization.setCreditCode(organization.getCreditCode());
            orgSourceOrganization.setTaxpayerCode(organization.getTaxpayerCode());
            orgSourceOrganization.setLicense(organization.getLicense());
            orgSourceOrganization.setRegisterTime(organization.getCreateTime());
            orgSourceOrganization.setAuthFile(organization.getAuthFile());
            orgSourceOrganization.setPerAuthFile(organization.getPerAuthFile());
            orgSourceOrganization.setEntAuthFile(organization.getEntAuthFile());
            OrganizationSourceDO orgSource = orgSourceMap.getOrDefault(organization.getOrganizationSourceId(), new OrganizationSourceDO());
            orgSourceOrganization.setOrgSource(orgSource.getOrgSource());
            result.add(orgSourceOrganization);
        }
        return new PageVO<>(organizationPageInfo.getTotalElements(), result);
    }

    @Override
    public Boolean updateSourceEnterInfo(OrgSourceOrganizationVO orgSourceOrganization) {

        Long organizationId = orgSourceOrganization.getOrganizationId();
        if (organizationId == null) {
            OrganizationDO organization = new OrganizationDO();
            BeanUtils.copyProperties(orgSourceOrganization, organization);
            organization.setType(OrganizationType.ENTER);
            organization.setState(SysOnOffState.ON);
            organization.setAuthState(StringUtil.isEmpty(orgSourceOrganization.getAuthFile()) ? AuthState.TO_VERIFY : AuthState.PASS);
            organizationDao.save(organization);
        } else {
            OrganizationDO existOrg = organizationDao.findByIdAndDeletedFalse(organizationId);
            AssertUtil.assertNotNull(existOrg, OrganizationExceptionEnum.ORGANIZATION_NOT_EXIST);
            existOrg.setEnterName(orgSourceOrganization.getEnterName());
            existOrg.setOrganizationSourceId(orgSourceOrganization.getOrgSourceId());
            existOrg.setEnterAddr(orgSourceOrganization.getEnterAddr());
            existOrg.setCreditCode(orgSourceOrganization.getCreditCode());
            existOrg.setTaxpayerCode(orgSourceOrganization.getTaxpayerCode());
            existOrg.setLicense(orgSourceOrganization.getLicense());
            existOrg.setAuthFile(orgSourceOrganization.getAuthFile());
            if (existOrg.getAuthState().name().equals(AuthState.TO_VERIFY.name())) {
                existOrg.setAuthState(StringUtil.isEmpty(orgSourceOrganization.getAuthFile()) ? AuthState.TO_VERIFY : AuthState.PASS);
            }
            existOrg.setPerAuthFile(orgSourceOrganization.getPerAuthFile());
            existOrg.setEntAuthFile(orgSourceOrganization.getEntAuthFile());
            organizationDao.save(existOrg);
        }
        return true;
    }

    @Override
    public void downloadSourceEnterTemplate(HttpServletResponse response) {

        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("来源企业信息", "Sheet1", ExcelType.XSSF),
                OrganizationNameVO.class, new ArrayList<>());
        try {
            ExcelUtil.downLoadExcel("来源企业信息", response, workbook);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}
